#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 5;

int d[MAX],v[MAX],a[MAX],p[MAX];
int candel[MAX];
struct nodec{
    int stpos;
    int edpos;
}carnode[MAX];
int nodenum = 0;
bool isnotover(int x0,int v0,int a,int p,int limitv)
{

    long long dis_x_to_p = p-x0;
    long long tmp = v0*v0;
    tmp+=2*a*dis_x_to_p;
    long long limtmp = limitv*limitv;
    return tmp<=limtmp;
}
bool cmp(nodec a,nodec b)
{
    if(a.stpos!=b.stpos)return a.stpos < b.stpos;
    else return a.edpos < b.edpos;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    freopen("detect.in","r",stdin);
    freopen("detect.out","w",stdout);
    int _T;
    long long n,m,L,V;
    cin>>_T;
    while(_T--)
     {
         nodenum = 0;
         int mxstp = -1;
         cin>>n>>m>>L>>V;
         for(int i = 1;i <= n;i++)
         {
            cin>>d[i]>>v[i]>>a[i];
         }
         for(int i = 1;i <= m;i++)
         {
             cin>>p[i];
         }
         int ans_overnum = 0;
         for(int i = 1;i <= n;i++)
         {
             if(a[i]>=0)
             {
                int foundc = -1;
                 int mt = lower_bound(p+1,p+m+1,d[i])-p;
                 for(int j = mt;j <= m;j++)
                 {
                    if(isnotover(d[i],v[i],a[i],p[j],V))
                    {
                        //passed
                    }
                    else
                    {
                        foundc = j;
                        break;
                    }
                 }
                 if(foundc == -1)
                 {
                     //itdoesn't overspeed at all
                     continue;
                 }
                 else
                 {
                     //foundc-m
                     //at least detected at foundc
                     mxstp = max(mxstp,foundc);
                     ans_overnum++;
                 }
             }
             else{
                //a < 0
                int foundc = -1;//the largest:over
                long long endposp = (v[i]*v[i])/(-2*a[i]);//-(v^2)/2a
                endposp+=d[i];
                endposp = max(endposp,L);
                int startt = lower_bound(p+1,p+m+1,d[i])-p;
                int endt = upper_bound(p+1,p+m+1,L)-p-1;
                for(int j = startt;j <= endt;j++)
                {
                    if(isnotover(d[i],v[i],a[i],p[j],V))
                    {
                        //passed
                        foundc = j-1;break;
                    }
                    else
                    {
                        //foundc = j;break;
                    }
                }
                if(foundc == -1)foundc = endt;
                if(foundc == startt-1)
                 {
                     //itdoesn't overspeed at all
                     continue;
                 }
                 else
                 {
                     //startt-foundc
                     //at least detected at foundc
                     ans_overnum++;
                     carnode[++nodenum].stpos =startt;
                     carnode[nodenum].edpos =foundc;
                 }
             }
         }
        /*if(mxstp!=-1)
        {
            carnode[++nodenum].stpos = mxstp;
            carnode[nodenum].edpos = m;
        }
        sort(carnode+1,carnode+nodenum+1,cmp);*/

         cout<<ans_overnum<<" "<<m-1<<"\n";
     }
    return 0;
}
